#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>
#include <QTextStream>
#include <QAction>
#include <QTime>

#include "robot.h"
#include "robotaction.h"
#include "troycontroller.h"
#include "troyglcontroller.h"
#include "newactiondialog.h"
#include "keyframedialog.h"
#include "audiodialog.h"

#ifdef KINECT
#include "Kinect/kinect.h"
#include "Kinect/kinectskeleton.h"
#include "GUI/kinect/kinectcalibrationdialog.h"
#endif

#ifdef WIIMOTE
#include "qwiimote.h"
#include "GUI/wiimote/wiimotewidget.h"
#include "GUI/wiimote/wiimotestatusdialog.h"
#endif

#ifdef TROY_INTERFACE
#include "Robot/troy.h"
#include "Robot/robotpose.h"
#endif

#include "ctrldialog.h"
#include "RobotController.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
#ifdef WIIMOTE
    , public WiimoteWidget
#endif
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

#ifdef WIIMOTE
    void associateWiimote(WiimoteStatusDialog *dialog);
#endif

    void playAction(QString actionFileName);
public slots:
    void showCtrlDialog();

public slots:
    void startController(void);
    void stopController(void);
    void runController(void);
    void pauseController(void);

private:
    Ui::MainWindow *ui;
    Robot* _robot;
    TroyGLController* _controller;
    RobotAction* _curAction;

    CRobotController * mpRobotController;
    ctrlDialog * mpCtrlDialog;

    NewActionDialog* _newActionDialog;

    QString _curFileName;

#ifdef TROY_INTERFACE
    troy::Troy* troy;
    QTime troyTimer;
#endif

#ifdef KINECT
    kinect::Kinect* _kinect;
    kinect::KinectSkeleton* _skeleton;

    QAction* _initializeKinectAction;
    QAction* _calibrateKinectAction;
    QAction* _captureKinectKeyFrameAction;
    //QAction* _kinectSnapshotRecorderAction;
    QAction* _kinectStreamRecorderAction;

    bool _inCalibration;
#endif

#ifdef WIIMOTE
    qWiimote* _wiimote;
    WiimoteStatusDialog* _wiimoteDialog;

    QAction* _connectWiimoteAction;
    QAction* _disconnectWiimoteAction;
    QAction* _showWiimoteStatusDialogAction;
#endif

    void loadAction(RobotAction* action);

public slots:
    void newAction();
    void allowGLEditing(bool allowed);
    void createDefaultAction();

    //void insertKeyFrame(MotionKeyFrame keyFrame);
    void append(RobotAction* action);

private slots:
    //History
    void historyStatus(bool undo, bool redo, QString undoTip, QString redoTip);

    //File menu
    void onOpenFile();
    void onSaveFile();
    void onSaveAs();

    //Action events
    void onActionStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State prevState);
    void onKeyFrame(int msec);
    void onSoundPlayed(int msec, QString name);
    void onSoundFinished(int msec, QString name);
    void prevKeyFrame();
    void nextKeyFrame();

    //GLWidget events
    void onGLMouseMove(double x, double y, double z);
    void onComponentSelected(const unsigned int* componentNames);
    void onSelectionCleared();
    void onGLEditFinished();

    //Button events
    void onMirrorLRButtonClicked();
    void onMirrorRLButtonClicked();
    void onIKLeftButtonClicked();
    void onIKRightButtonClicked();
    void togglePlayPause();

    void setSelectionInfo(QString info);
    void appendEventInfo(QString info);

    void onEditingKeyFrame(int timestamp);
    void onEditingSound(int timestamp);
    void onTimelineEditFinish();
private:
    void moveEvent(QMoveEvent *event);
#ifdef KINECT
private slots:
    void onDialogClose(int result);

    bool initializeKinect();
    void captureKinectKeyFrame();
    //void kinectSnapshotRecord();
    void kinectStreamRecord();
    void calibrateKinect();

    void receiveMessage(QString message, Message::Priority priority);
#endif
#ifdef WIIMOTE
private slots:
    bool connectWiimote();
    void disconnectWiimote();
    void showWiimoteStatusDialog();
#endif
#ifdef TROY_INTERFACE
private slots:
    void updateTroy();
#endif

signals:
    void stopAnimation(void);
    void setActionTimeLine(int msec);
private:
    void executeAction(void);
    void resetTimeLine(void);

};

#endif // MAINWINDOW_H
